package com.school.manager.utils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import com.school.manager.enums.ExceptionEnum;
import com.school.manager.exception.BussinessException;
import com.school.manager.interfaces.ITree;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.crypto.digest.DigestUtil;
import lombok.SneakyThrows;

/**
 * description：转换工具
 * date：2021/10/1510:05 上午
 */

public class ConvertUtil {

    private ConvertUtil() {
    }

    /**
     * 对象转换
     *
     * @param resource 来源
     * @param clazz    目标类型
     * @param <T>
     * @return
     */
    @SneakyThrows
    public static <T> T convertObj(Object resource, Class<T> clazz) {
        if (ObjectUtil.isEmpty(resource)) {
            throw new BussinessException(ExceptionEnum.OBJECT_IS_NULL);
        }
        T target = ReflectUtil.newInstance(clazz);
        Field[] fields = ReflectUtil.getFields(clazz);
        for (Field field : fields) {
            // 判断是否有该属性
            if (ReflectUtil.hasField(resource.getClass(), field.getName())) {
                ReflectUtil.setFieldValue(target, field.getName(), ReflectUtil.getFieldValue(resource, field.getName()));
            }
        }
        return target;
    }

    /**
     * 集合转化
     *
     * @param resource 来源
     * @param clazz    目标类型
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K, V> List<V> convertList(Collection<K> resource, Class<V> clazz) {
        if (CollUtil.isEmpty(resource)) {
            return new ArrayList<>();
        }
        return resource.stream().map(tar -> ConvertUtil.convertObj(tar, clazz)).collect(Collectors.toList());
    }


    /**
     * 集合转二叉树
     *
     * @param resource  来源
     * @param predicate 顶级父级的标识
     * @return
     */
    public static <T extends ITree> List<T> convertTree(List<T> resource, Predicate<? super T> predicate) {
        List<T> result = resource.stream().filter(predicate).collect(Collectors.toList());
        // 移出父级元素
        resource.removeIf(result::contains);
        ConvertUtil.setChilder(result, resource);
        return result;
    }

    /**
     * 设置孩子
     *
     * @param parentList
     * @param elements
     * @param <T>
     */
    private static <T extends ITree> void setChilder(List<T> parentList, List<T> elements) {
        if (CollUtil.isEmpty(elements) || CollUtil.isEmpty(parentList)) {
            return;
        }
        // 遍历父级
        parentList.forEach(parent -> {
            List<T> childer = elements.stream().filter(element -> parent.getId().equals(element.getParentId())).collect(Collectors.toList());
            parent.setChildren(childer);
            elements.removeIf(childer::contains);
            setChilder(childer, elements);
        });
    }
    
    public static void main(String[] args) {
    	System.out.print(DigestUtil.md5Hex("123456"));
	}
}
